Thread: cannot convert parameter 3 from 'unsigned short *[]' to 'const unsigned short *[]'

  1. #1
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545

    cannot convert parameter 3 from 'unsigned short *[]' to 'const unsigned short *[]'

    All I did was make a function parameter const and now VC++ is complaining about:
    Code:
    cannot convert parameter 3 from 'unsigned short *[]' to 'const unsigned short *[]'
    I thought non-const pointers get promoted to const, but not the other way around. Does it work different for const wchar_t*[] types?

  2. #2
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    code?

  3. #3
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    A pointer's pointed-to type can have const added to it, but that's not the case here.

    What you have here is
    a) unsigned short **: pointer to 'pointer to unsigned short'
    b) const unsigned short **: pointer to 'pointer to const unsigned short'

    As you can see, the pointer did not just gain a const in the pointee. That would have been unsigned short *const *: pointer to 'const pointer to unsigned short'.

    Now, why doesn't this conversion work? Consider (using int instead of unsigned short):
    Code:
    const int ci = 4; // Valid
    const int *pci = &ci; // Valid
    int *pi; // Valid
    int **ppi = π // Valid
    const int **ppci = ppi; // Valid ???
    *ppci = pci; // Valid !!! (But pi now points at ci!)
    *pi = 5; // Changes ci!
    Allowing this conversion would allow subversion of the type system without any warning whatsoever.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  4. #4
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    I'm still a bit fuzzy on what's going on...
    I have something like this:
    Code:
    void Func( int argc, const TCHAR* argv[] );
    
    int _tmain( int argc, TCHAR* argv[], TCHAR* envp[] )
    {
        Func( argc, argv ); // error
    ...
    }
    I wanted to make Func() const-correct, to show that it doesn't modify argv, but when I added the const it complained. So how would I make Func() const-correct?

  5. #5
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    I think I just fixed it by changing Func() to:
    Code:
    void Func( int argc, const TCHAR* const argv[] );
    But I'm still not sure why it was complaining about the single const?

  6. #6
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    I believe CornedBee explained it well. You may want to take a look at his reply.

    But shortly, remember to read pointer declarations from right to left. That helps establish exactly what kind of pointer you have.

    In your first case you had a pointer to a pointer to const tchar.
    In your last case, you have a const pointer to a pointer to const TCHAR.

    In the first case your pointer wasn't const.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  7. #7
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Qualification conversions are described in 4.4 of the standard. The basic rule is:
    Quote Originally Posted by 4.4/1
    An rvalue of type "pointer to cv1 T" can be converted to an rvalue of type "pointer to cv2 T" if "cv2 T" is more cv-qualified than "cv1 T."
    OK, let's recap. In function arguments, [] is equivalent to *, so the type of main's argv (let's assume _UNICODE isn't defined, so it's TCHAR=char) is char**. Mapping this to the pattern "pointer to cv1 T", we end up with cv1=nothing and T=char*.
    The type of Func's argv is const char**. Mapped to the pattern, cv2=nothing and T=const char*.
    Since the Ts aren't equal, the primary rule of qualification conversion does not apply.

    If, on the other hand, Func's argv was char*const*, we'd get cv2=const and T=char*, meaning that the Ts are equal and cv2 is more cv-qualified than cv1. The rule applies, and conversion can be performed.

    Now this is where it gets complicated. Paragraph 4 starts:
    Quote Originally Posted by 4.4/4
    A conversion can add cv-qualifiers at levels other than the first in multi-level pointers, subject to the following rules:
    The rules are described formally and are thus hard to understand. It boils down to two rules:
    1) You can't remove anything.
    2) If you add const or volatile somewhere, you have to add const to all pointers "further out", too.

    Some examples:
    Code:
    int * const * const volatile * volatile *p1;
    int * const * const * volatile *p2 = p1; // Not allowed: removes something.
    int * const * const volatile * const volatile *p3 = p1; // Allowed: const added at outermost level.
    int *const volatile * const volatile * volatile *p4 = p1; // Not allowed: change, but not all levels further out
                                                              // (to the right of the change) are const.
    const int * const * const volatile * volatile *p5 = p1; // Not allowed: as above.
    const int * const * const volatile * const volatile *p6 = p1; // Allowed: change at innermost type, but everything to the right is const.
    In your case, your last try was const TCHAR*const *, which is valid. You added const to the leftmost type, but also to everything to the right of it.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  8. #8
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Thanks, I think I sort of understand now, kind of.
    Next time I have trouble falling asleep, I'll just start reading one of those standards.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Drawing Program
    By Max_Payne in forum C++ Programming
    Replies: 21
    Last Post: 12-21-2007, 05:34 PM
  2. Heap corruption using zlib inflate
    By The Wazaa in forum C++ Programming
    Replies: 0
    Last Post: 03-29-2007, 12:43 PM
  3. Please Help - Problem with Compilers
    By toonlover in forum C++ Programming
    Replies: 5
    Last Post: 07-23-2005, 10:03 AM
  4. simulate Grep command in Unix using C
    By laxmi in forum C Programming
    Replies: 6
    Last Post: 05-10-2002, 04:10 PM
  5. oh me oh my hash maps up the wazoo
    By DarkDays in forum C++ Programming
    Replies: 5
    Last Post: 11-30-2001, 12:54 PM